#ifndef net_types_h
#define net_types_h

#define LOW_RATE_THRESH    20000
#define LOW_RATE_SCALE_FACTOR  8

#define MAX_MPF_ADDRS    4

#include <netinet/in.h>

struct ipv6_addr {
  u_char addr [16];
};

struct addrs {
  union {
    uint32_t ipv4_addr;
    struct in6_addr ipv6_addr;
  } nl_head;
  int nl_protocol;
};

/* move this route struct from scpstp.h to here (net_types.h) */
typedef struct _route
  {
    struct _route *next;
    unsigned char IFNAME [16];
    uint32_t bytes_per_interval;
    uint32_t current_credit;
    uint32_t shifted_bytes_per_interval;
    uint32_t shifted_rate_bucket;
    uint32_t  attrib_list;
    int min_rate;
    uint32_t max_credit;
    uint32_t max_burst_bytes;
    uint32_t interval;
    uint32_t time;
    uint32_t prev_time;
    unsigned int MTU;
    unsigned int SMTU;
    unsigned int MSS_FF;
    unsigned int TCPONLY;
    unsigned int DIV_ADDR;
    unsigned int DIV_PORT;
    uint32_t flags;
    uint32_t rtt;
    uint32_t rtt_var;
    uint32_t initial_RTO;
    uint32_t sendpipe;
    int cong_control;
    int rate;
    int encrypt_ipsec;
    int encrypt_pre_overhead;
    int encrypt_block_size;
    int encrypt_post_overhead;
    uint32_t new_params_flag;
    uint32_t dst_ipaddr;
    uint32_t dst_netmask;
    uint32_t src_ipaddr;
    uint32_t src_netmask;
    unsigned short dst_higport; 
    unsigned short dst_lowport;
    unsigned short src_higport;
    unsigned short src_lowport;
    uint32_t protocol_id;
    int dscp;
    int lan_wan;

    unsigned int route_sock_id;
    int flow_control;
    int flow_control_cap;

  }
route;

#define GW_LOST_RATE      0
#define GW_USING_RATE      1
#define GW_LOST_AND_REGAINED_RATE  2

#define RESET_USING_RATE    1
#define RESET_LOST_AND_REGAINED_RATE  2

#define MIN_IP_HDR      20

/** WARNING! IF THESE VALUES ARE CHANGED, THE CODE
*** IN SCPS_NP.C: scps_np_get_template MUST ALSO BE
*** CHANGED, SINCE THE TS HDR MASKING DEPENDS ON
*** THESE VALUES.
**/
typedef enum {
  None,
  ISO24,
  TBD24,
  SCPS32
} ts_fmt;

typedef struct _scps_np_ts {
    ts_fmt format;
    short ts_val[2];
} scps_ts;

typedef struct _scps_np_bqos
  {
    u_short precedence;
    u_short routing;
    u_short pro_specific;
  }
scps_np_bqos;

typedef struct _scps_np_eqos {
    u_short ip_precedence;
    u_short ip_tos;
}
scps_np_eqos;

/* NOTE: int_del & cksum are new fields here;
         also, dst & src addrs are now 'ip' not np
*/

typedef struct _scps_np_rqts {
    //scps_tpid tpid;
    uint8_t tpid;
    int nl_protocol;
    uint32_t ipv4_dst_addr;
    uint32_t ipv4_src_addr;
    struct in6_addr ipv6_dst_addr;
    struct in6_addr ipv6_src_addr;
    scps_ts timestamp;
    scps_np_bqos bqos;
    scps_np_eqos eqos;
    BOOL cksum;
    BOOL int_del;
    unsigned char DSCP;
    void *gwio;
    int32_t divert_port_number;
    unsigned char src_mac_addr [6];
    unsigned char dst_mac_addr [6];
    unsigned short frame_type;
    int recv_tap_if;
    int peer_tap_if;
} scps_np_rqts;

/* since there was no set use for the bitmask and pointers
** fields, I'm using the pointers to 'point' to input
** fields in the header that can change between _get_template 
** and _trequest. So far, the only dynamic fields are the
** timestamp and the secondary header. I've picked pointers[0]
** to hold the pointer (header octet number) to the timestamp,
** and pointers[1] to hold ptr to the secondary hdr.
*/
typedef struct
  {
    short hdr_len;
    uint32_t bitmask;
    short pointers[10];
    uint8_t header[84];
    uint32_t dst_npaddr;
    uint32_t src_npaddr;

  }
scps_np_template;

typedef struct _scps_sp_rqts
  {
    scps_np_rqts np_rqts;
    short tpid;
    short sprqts;
  }
scps_sp_rqts;

#endif /* net_types_h */
